package com.IDWORLD;

import static android.app.PendingIntent.FLAG_IMMUTABLE;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;

import java.util.HashMap;

public class HostUsb {
    private static final String TAG = "OpenHostUsb";

    private static final boolean D = false;

    private static final String ACTION_USB_PERMISSION = "com.IDWORLD.USB_PERMISSION";

    private Context context = null;

    private UsbManager mDevManager = null;

    private UsbInterface intf = null;

    private UsbDeviceConnection connection = null;

    private UsbDevice device = null;

    private int m_nEPOutSize = 2048;

    private int m_nEPInSize = 2048;

    private byte[] m_abyTransferBuf = new byte[2048];

    UsbEndpoint endpoint_IN = null;

    UsbEndpoint endpoint_OUT = null;

    UsbEndpoint endpoint_INT = null;

    UsbEndpoint curEndpoint = null;

    private final BroadcastReceiver mUsbReceiver;

    private static void writeLog(String fileName, String content) {
        Log.e("OpenHostUsb", content);
    }

    public boolean AuthorizeDevice(Context paramContext, int VID, int PID) {
        this.context = paramContext;
        this.mDevManager = (UsbManager)this.context.getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = this.mDevManager.getDeviceList();
        for (UsbDevice tdevice : deviceList.values()) {
            if (tdevice.getVendorId() == VID && tdevice.getProductId() == PID) {
                boolean hasPermission = this.mDevManager.hasPermission(tdevice);
                if (!hasPermission) {
                    PendingIntent permissionIntent = PendingIntent.getBroadcast(this.context, 0, new Intent("com.IDWORLD.USB_PERMISSION"), FLAG_IMMUTABLE);
                    this.context.registerReceiver(this.mUsbReceiver, new IntentFilter("com.IDWORLD.USB_PERMISSION"));
                    this.context.registerReceiver(this.mUsbReceiver, new IntentFilter("android.hardware.usb.action.USB_DEVICE_DETACHED"));
                    this.mDevManager.requestPermission(tdevice, permissionIntent);
                    return true;
                }
                this.device = tdevice;
                return true;
            }
        }
        return false;
    }

    public HostUsb() {
        this.mUsbReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if ("com.IDWORLD.USB_PERMISSION".equals(action))
                    synchronized (context) {
                        HostUsb.this.device = (UsbDevice)intent.getParcelableExtra("device");
                        if (!intent.getBooleanExtra("permission", false) ||
                                HostUsb.this.device != null);
                    }
            }
        };
    }

    public boolean WaitForInterfaces() {
        int timeover = 0;
        while (this.device == null) {
            timeover++;
            try {
                Thread.sleep(10L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (timeover > 1000)
                return false;
        }
        return true;
    }

    public int OpenDeviceInterfaces() {
        UsbDevice mDevice = this.device;
        int fd = -1;
        if (mDevice == null)
            return -1;
        this.connection = this.mDevManager.openDevice(mDevice);
        if (!this.connection.claimInterface(mDevice.getInterface(0), true))
            return -1;
        if (mDevice.getInterfaceCount() < 1)
            return -1;
        this.intf = mDevice.getInterface(0);
        if (this.intf.getEndpointCount() == 0)
            return -1;
        for (int i = 0; i < this.intf.getEndpointCount(); i++) {
            if (this.intf.getEndpoint(i).getType() == 2) {
                if (this.intf.getEndpoint(i).getDirection() == 128) {
                    this.endpoint_IN = this.intf.getEndpoint(i);
                } else if (this.intf.getEndpoint(i).getDirection() == 0) {
                    this.endpoint_OUT = this.intf.getEndpoint(i);
                }
            } else if (this.intf.getEndpoint(i).getType() == 3) {
                this.endpoint_INT = this.intf.getEndpoint(i);
            }
        }
        this.curEndpoint = this.intf.getEndpoint(0);
        if (this.connection != null) {
            fd = this.connection.getFileDescriptor();
            return fd;
        }
        return -1;
    }

    public void CloseDeviceInterface() {
        if (this.connection != null) {
            this.connection.releaseInterface(this.intf);
            this.connection.close();
        }
    }

    public boolean USBBulkSend(byte[] pBuf, int nLen, int nTimeOut) {
        int n = nLen / this.m_nEPOutSize;
        int r = nLen % this.m_nEPOutSize;
        int i;
        for (i = 0; i < n; i++) {
            System.arraycopy(pBuf, i * this.m_nEPOutSize, this.m_abyTransferBuf, 0, this.m_nEPOutSize);
            int w_nRet = this.connection.bulkTransfer(this.endpoint_OUT, this.m_abyTransferBuf, this.m_nEPOutSize, nTimeOut);
            if (w_nRet != this.m_nEPOutSize)
                return false;
        }
        if (r > 0) {
            System.arraycopy(pBuf, i * this.m_nEPOutSize, this.m_abyTransferBuf, 0, r);
            int w_nRet = this.connection.bulkTransfer(this.endpoint_OUT, this.m_abyTransferBuf, r, nTimeOut);
            if (w_nRet != r)
                return false;
        }
        return true;
    }

    public boolean USBBulkReceive(byte[] pBuf, int nLen, int nTimeOut) {
        int n = nLen / this.m_nEPInSize;
        int r = nLen % this.m_nEPInSize;
        int i;
        for (i = 0; i < n; i++) {
            int w_nRet = this.connection.bulkTransfer(this.endpoint_IN, this.m_abyTransferBuf, this.m_nEPInSize, nTimeOut);
            if (w_nRet != this.m_nEPInSize)
                return false;
            System.arraycopy(this.m_abyTransferBuf, 0, pBuf, i * this.m_nEPInSize, this.m_nEPInSize);
        }
        if (r > 0) {
            int w_nRet = this.connection.bulkTransfer(this.endpoint_IN, this.m_abyTransferBuf, r, nTimeOut);
            if (w_nRet != r)
                return false;
            System.arraycopy(this.m_abyTransferBuf, 0, pBuf, i * this.m_nEPInSize, r);
        }
        return true;
    }
}
